#include <USBKeyboardMiku.h>

#define LAYOUT LAYOUT_US

// Setup Miku button mapping
#define TRANGLE   13
#define SQUARE    12
#define CROSS     11
#define CIRCLE    10

#define START     9

#define L_S_LEFT  A3
#define L_S_RIGHT A2
#define R_S_LEFT  A1
#define R_S_RIGHT A0

const uint8_t KEY_ARRAY[9] = { TRANGLE,SQUARE,CROSS,CIRCLE,START,L_S_LEFT,L_S_RIGHT,R_S_LEFT,R_S_RIGHT };
const uint8_t KEY_CODES[9] = { 26,4,22,7,40,20,8,24,18 };
uint8_t KEY_BUFFER_LAST[9] = { 0,0,0,0,0,0,0,0,0 };
uint8_t KEY_BUFFER_NOW[9] = { 0,0,0,0,0,0,0,0,0 };
uint8_t HID_BUFFER[6] = { 0,0,0,0,0,0 };

bool updateReport = false;

USBKeyboard mKeyboard = USBKeyboard();

void setup() {
  // put your setup code here, to run once:
  //Serial.begin(115200);
  // Init Miku button pins
  initButtonPins();
  
  // Disable TIMER interrupt
  //TIMSK0 = 0; //For Atmega328p
  TIMSK = 0; //For Atmega8
  
}

void initButtonPins() {
  for (uint8_t i = 0; i < 9; ++i)
  {
    pinMode(KEY_ARRAY[i], INPUT_PULLUP);
  }
}

void loop() {
  // put your main code here, to run repeatedly:

  // Keep USB live
  mKeyboard.update();
  
  // Read all key state
  readButtonState();

  // Check key press changed or not
  keyPressChanged();
  
  // Send key to HID
  if (updateReport)
  {
    sendKeyCodeToHID();
  }

  delayMicroseconds(20000);
}

void readButtonState() {
  
  for (uint8_t i = 0; i < 9; ++i)
  {
    bool buttonState = digitalRead(KEY_ARRAY[i]);

    if (buttonState == LOW)
    {
      KEY_BUFFER_NOW[i] = 1;
    }
    else
    {
      KEY_BUFFER_NOW[i] = 0;
    }
  }
}

void keyPressChanged()
{
  for (uint8_t i = 0; i < 9; ++i)
  {
    if (KEY_BUFFER_NOW[i] != KEY_BUFFER_LAST[i])
      updateReport = true;

    KEY_BUFFER_LAST[i] = KEY_BUFFER_NOW[i];
  }
}

void sendKeyCodeToHID() {
  uint8_t idx = 0;
  
  for (uint8_t i = 0; i < 9; ++i)
  {
    if (KEY_BUFFER_NOW[i] == 1)
    {
      HID_BUFFER[idx] = KEY_CODES[i];
      ++idx;
    }
  }
  
  //Serial.print(HID_BUFFER[0]);
  //Serial.print(" ");
  //Serial.print(HID_BUFFER[1]);
  //Serial.print(" ");
  //Serial.print(HID_BUFFER[2]);
  //Serial.print(" ");
  //Serial.print(HID_BUFFER[3]);
  //Serial.print(" ");
  //Serial.print(HID_BUFFER[4]);
  //Serial.print(" ");
  //Serial.print(HID_BUFFER[5]);
  //Serial.println(" ");
  
  mKeyboard.sendReport(0,HID_BUFFER[0],HID_BUFFER[1],HID_BUFFER[2],HID_BUFFER[3],HID_BUFFER[4],HID_BUFFER[5]);

  //HID_BUFFER[6] = { 0,0,0,0,0,0 };
  for (uint8_t i = 0; i < 6; ++i)
  {
    HID_BUFFER[i] = 0;
  }
}
